/*
 * @(#)ServiceLocator.java 1.0 2005-2-26
 * Copyright 2005 VandaGroup, Inc. All rights reserved.
 */
package com.vanda.db.pk;
import com.vanda.db.SQLAccessor;
import com.vanda.exception.VandaException;
/**
 * 类说明: <br>
 * 通用主键工具类 - 主键类 <br>
 * 需要数据库表支持： CREATE TABLE CFI_SYS_KEYTABLE ( KEY_NAME VARCHAR2(100) NOT NULL,
 * KEY_VALUE NUMBER, CONSTRAINT PK_CFI_SYS_KEYTABLE PRIMARY KEY (KEY_NAME) )
 * 
 * @author 蒋勇 <br>
 * @version Version 1.00 <br>
 */
public class KeyInfo {
    /** 最大值 */
    private long keyMax;
    /** 最小值 */
    private long keyMin;
    /** 键的名字 */
    private String keyName;
    /** 当前值 */
    private long nextKey;
    /** 缓存大小 */
    private int poolSize;

    /**
     * 构造函数(用于查询当前键值做查询条件)
     * @author chenlei 20070127
     */
    public KeyInfo(String keyName)
            throws VandaException {        
        this.keyName = keyName;
    }
    
    /**
     * 构造函数
     */
    public KeyInfo(int poolSize, String keyName, SQLAccessor accessor)
            throws VandaException {
        this.poolSize = poolSize;
        this.keyName = keyName;
        retrieveFromDB(accessor);
    }

    /**
     * 取值方法，提供键的最大值
     * 
     * @return
     * @author:蒋勇
     * @modify:
     */
    public long getKeyMax() {
        return keyMax;
    }

    /**
     * 取值方法，提供键的最小值
     * 
     * @return
     * @author:蒋勇
     * @modify:
     */
    public long getKeyMin() {
        return keyMin;
    }

    /**
     * 取值方法，提供键的当前值,如果当前键值大于最大值,则重数据库取最新的键值返回;
     * 
     * @param con
     * @return
     * @author:蒋勇
     * @modify:
     */
    public long getNextKey(SQLAccessor accessor) throws VandaException {
        if (nextKey > keyMax) {
            retrieveFromDB(accessor);
        }
        return nextKey++;
    }

    /**
     * 取当前值
     * 
     * @param con
     * @return
     * @author:蒋勇
     * @modify:
     */
    public long getCurrentKey(SQLAccessor accessor) throws VandaException {
    	long value = -1;
    	try{
	        KeyValue key = (KeyValue) accessor.findName("pk:getKey", this);
	        if (key != null) {
	            value = key.getKeyValue();
	        }
	    } catch (Exception e) {
	        e.printStackTrace();
	        throw new VandaException(e);
	    }

        return value;
    }
    
    /**
     * 设置当前值
     * @param accessor
     * @param value
     * @throws VandaException
     */
    public synchronized void setCurrentValue(SQLAccessor accessor,long value) throws VandaException{
    	nextKey = value;
        try {
        	accessor.executeName("pk:updateCurrentKey", this);
        } catch (Exception e) {
            e.printStackTrace();
            throw new VandaException(e);
        }
    }
    
    /**
     * 内部方法，从数据库提取键的当前值
     * 
     * @param con
     * @author:蒋勇
     * @modify:
     */
    private void retrieveFromDB(SQLAccessor accessor) throws VandaException {
        //		DBAccessor accessor = DBAccessor.getInstance();
        try {
            long keyFromDB = poolSize;
            int[] counts = accessor.executeName("pk:updateKey", this);
            if (counts[0] == 0) {
                accessor.executeName("pk:createKey", this);
            } else {
                KeyValue key = (KeyValue) accessor.findName("pk:getKey", this);
                if (key != null) {
                    keyFromDB = key.getKeyValue();
                }
            }
            keyMax = keyFromDB;
            keyMin = keyFromDB - poolSize + 1;
            nextKey = keyMin;
        } catch (Exception e) {
            e.printStackTrace();
            throw new VandaException(e);
        }
    }

    /**
     * 方法说明: 缓存大小
     * 
     * @return
     * @author wkf3915 2005-8-10
     */
    public int getPoolSize() {
        return poolSize;
    }

    /**
     * 方法说明: 缓存大小
     * 
     * @param
     * @author wkf3915 2005-8-10
     */
    public void setPoolSize(int i) {
        poolSize = i;
    }

    /**
     * 方法说明: 最大值
     * 
     * @return
     * @author wkf3915 2005-8-10
     */
    public String getKeyName() {
        return keyName;
    }

	public long getNextKey() {
		return nextKey;
	}
	
	public void setNextKey(long nextKey) {
		this.nextKey = nextKey;
	}
}